function CategoryManagerView(controller, div, messager) {

	var self = this;
	this.map = {};
	this.selectedCategory = null;
	var createDialog = new InputDialog('createCategoryDialog', null);
	var updateDialog = new InputDialog('updateCategoryDialog', function(name) {
		if(self.selectedCategory.name !== name) {
			controller.updateCategory(self.selectedCategory.id, name);
		}
	});

	this.attachContextMenu = function(contextMenu) {
		var rootMenu = [
			{ "id": "1", "label": "Изменить" },
			{ "id": "2", "label": "Добавить в" }
		];
		var nodeMenu = [
			{ "id": "1", "label": "Изменить" },
			{ "id": "2", "label": "Добавить в" },
			{ "id": "3", "label": "Добавить до" },
			{ "id": "4", "label": "Добавить после" },
			{ "id": "5", "label": "Удалить" }
		];

		var items = $('#categoryTree').jqxTree('getItems');
		$.each(items, function(index, item) {
			$(item.element).on('mousedown', function(event) {
				var target = $(event.target).parents('li:first')[0];
				var rightClick = isRightClick(event);
				if (rightClick && target != null) {
					$("#categoryTree").jqxTree('selectItem', item.element);
					var scrollTop = $(window).scrollTop();
					var scrollLeft = $(window).scrollLeft();
					if(item.parentId == null || item.parentId === 0) {
						contextMenu.jqxMenu({ source: rootMenu, height: 56 });
					} else {
						contextMenu.jqxMenu({ source: nodeMenu, height: 136 });
					}
					contextMenu.jqxMenu('open', parseInt(event.clientX) + 5 + scrollLeft, parseInt(event.clientY) + 5 + scrollTop);
					return false;
				}
			});
			$(item.element).bind('dblclick', function(event) {
				updateDialog.show('Редактирование категории', self.selectedCategory.name);
			});
		});
	};

	this.init = function() {
		var html = '<table class="table-layout">' +
			'<tr><td align="center"><b>Категории:</b></td></tr>' +
			'<tr><td><div id="categoryTree"></div></td></tr>' +
			'<tr><td><div id="categoryMenu"></div>' +
					'<div id="createCategoryDialog"></div>' +
					'<div id="updateCategoryDialog"></div></td></tr>' +
			'</table>';
		$(div).html(html);
		createDialog.init();
		updateDialog.init();
		$('#categoryTree').jqxTree({ width: 230, height: 285, allowDrag: true, allowDrop: true,
			dragEnd: function (item, dropItem, args, dropPosition, tree) {
				if(!dropPosition) {
					return false;
				} else if(item.parentId == null || item.parentId === 0) {
					messager.showWarning('Корневые категории перемещать нельзя', 3000);
					return false;
				} else if(dropPosition !== 'inside' && (dropItem.parentId == null || dropItem.parentId === 0)) {
					messager.showWarning('Перемещать категории в корень нельзя', 3000);
					return false;
				} else {
					return controller.moveCategory(item.id, dropItem.id, dropPosition, false);
				}
			}
		});
		$('#categoryTree').on('select', function(event) {
			var item = $('#categoryTree').jqxTree('getItem', event.args.element);
			self.selectedCategory = self.map[item.id];
		});
		$('#categoryTree').jqxTree('expandAll');

		$("#categoryMenu").jqxMenu({ width: '140px', autoOpenPopup: false, mode: 'popup' });

		$("#categoryMenu").on('itemclick', function (event) {
			var choice = event.args.id;
			switch (choice) {
				case "1":
					updateDialog.show('Редактирование категории', self.selectedCategory.name);
					break;
				case "2":
					createDialog.handler = function(name) {
						controller.createCategory(name, self.selectedCategory.id, 'inside');
					};
					createDialog.show('Новая категория в ' + self.selectedCategory.name, null);
					break;
				case "3":
					createDialog.handler = function(name) {
						controller.createCategory(name, self.selectedCategory.id, 'before');
					};
					createDialog.show('Новая категория до ' + self.selectedCategory.name, null);
					break;
				case "4":
					createDialog.handler = function(name) {
						controller.createCategory(name, self.selectedCategory.id, 'after');
					};
					createDialog.show('Новая категория после ' + self.selectedCategory.name, null);
					break;
				case "5":
					//todo: check for category childs and ask confirm for removing all of them
					controller.removeCategory(self.selectedCategory.id);
					break;
				default :
					break;
			}
		});

		// disable the default browser's context menu.
		$(document).on('contextmenu', function (e) {
			if ($(e.target).parents('.jqx-tree').length > 0) {
				return false;
			}
			return true;
		});
		return this;
	};

	this.updateCategories = function(categories) {
		var source = {
			datatype: 'array',
			datafields: [
				{ name: 'id' },
				{ name: 'name' },
				{ name: 'parentId' }
			],
			id: 'id',
			localdata: categories
		};
		this.map = {};
		$.each(categories, function(index, category) {
			self.map[category.id] = category;
		});

		var dataAdapter = new $.jqx.dataAdapter(source);
		dataAdapter.dataBind();
		var records = dataAdapter.getRecordsHierarchy('id', 'parentId', 'items', [{ name: 'name', map: 'label' }]);
		$('#categoryTree').jqxTree({ source: records });
		$('#categoryTree').jqxTree('expandAll');
		this.attachContextMenu($("#categoryMenu"));
	};
};